#!/usr/bin/python

import os
import socket
import fcntl
import struct
import time
import subprocess
from subprocess import *
from threading import *

from ivic.core import Utils
from ivic.core import Logging
from ivic.core.Utils import GenUUID
from ivic.vspace.Server import  *
from ivic.vspace.Config import  *

from ivic.vspace.ServerMonitor import *

logger = Logging.get_logger('ivic.vspace.Vspace')


#****************get_ip_address function********************#
def get_ip_address(nicname):
    """get the ip address of the server
       the nicname is : eth0 or eth1 or lo.....
                        lo means loopback address
    """
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(),
        0x8915,
        struct.pack('256s', nicname[:15])
        )[20:24])
#***********************************************************#

class VSpace(Thread):
    
    host_ip_addr = None
    
    def __init__(self, user, resolution, reporter):
        Thread.__init__(self)
        self.uuid = GenUUID()
        self.user = user
        self.state = 'inited'
        self.resolution = resolution
        self.vnc_address = ''
        self.vnc_port = ''
        self.create_time = ''
        self.end_time = ''
        self.setName("Thread VSpace %s" % self.uuid)
        self.reporter = reporter
        self.server_uuid = vspace_config.uuid
    
    def start(self):
        try:
            
            cmd = 'su - %s -c "vncserver -geometry %s"' % (vspace_config.common_user,self.resolution)
            ISOTIMEFORMAT = "%Y-%m-%d %X"
            create_time = time.strftime(ISOTIMEFORMAT, time.localtime())
            self.create_time = create_time
            output = subprocess.Popen(cmd, close_fds=True, stderr=PIPE, shell=True).communicate()[1]
            for line in output.split('\n'):
                if 'New' in line:
                     self.vnc_port = line.split(':')[-1]
                     break
#            self.vnc_port = output.split('\n')[1].split(':')[-1]
            #ip = Utils.#get_ip_address("eth0")
            if VSpace.host_ip_addr is None:
                ip = None
                try:
                    ip = Utils.external_address()
                except Exception, e:
                    pass
                
                if ip is None: ip =get_ip_address("eth0")
                VSpace.host_ip_addr = ip 
                    
            self.vnc_address = ':'.join([VSpace.host_ip_addr, self.vnc_port])
            self.state = 'running'
            self.trigger("START") 
        except Exception, e:
            logger.error('createvSpace:%s' % e)
        
    def kill(self):
        try:
            cmd = 'su - %s -c "vncserver -kill :%s"' %(vspace_config.common_user,self.vnc_port)
#            cmd = "".join([cmd, self.vnc_port])
            output = subprocess.Popen(cmd, close_fds=True, stderr=PIPE, shell=True).communicate()[1]            
            #self.trigger("STOP")
            self.state = 'stopped'
            ISOTIMEFORMAT = "%Y-%m-%d %X"
            self.end_time = time.strftime(ISOTIMEFORMAT, time.localtime())
            self.trigger("STOP")  
            logger.debug(output)
        except Eception, e:
            logger.error('vSpace:%s' % e)
    
    def poll(self):     
        if self.state == 'running':
            try:
                logger.debug("Try to poll the state of VSpace %s" % self.vnc_address)                        
#                pid_path = os.getenv('HOME') + '/.vnc'
                pid_path = os.path.join('/home',vspace_config.common_user,'.vnc/')
                print pid_path
                pid_filename = socket.gethostname() + ":" + self.vnc_port + '.pid'
                logger.debug("Detecting pid file: %s" % (pid_path + '/' + pid_filename))
                if not os.path.exists(pid_path + '/' + pid_filename):
                    self.state = "stopped"
                                      
            except Exception, e:
                self.state = 'stopped'
                logger.error("%s" % e)
            
            if self.state == "stopped":
                ISOTIMEFORMAT = "%Y-%m-%d %X"
                self.end_time = time.strftime(ISOTIMEFORMAT, time.localtime())
                self.trigger("STOP")
            elif self.state == "running":
                ISOTIMEFORMAT = "%Y-%m-%d %X"
                self.end_time = time.strftime(ISOTIMEFORMAT, time.localtime())
                self.trigger("RUNNING")  
            
    
    def run(self):
        self.start()
        
    def dict(self):
        vnc_dict = {
                    'user':self.user,
                    'server':self.server_uuid,
                    'vnc_address':self.vnc_address,
                    'create_time':self.create_time,
                    'end_time': self.end_time,
                    'uuid':self.uuid,
                    'state':self.state,
                    'resolution':self.resolution
                   }
        #logger.debug("apply dict function")
        return vnc_dict
    
    def trigger(self, eventType):
        try:
            self.reporter.putEvent(eventType, self.dict())
#            logger.debug("%s\t%s" % (eventType, self.dict()))
        except Exception, e:
           logger.error("%s" % e)
           
    def __str__(self):
        try:
            info = self.dict()
            if len(info['end_time']) < 1: info.pop('end_time')
            return repr(info)
        except Exception,e:
            logger.error("%s" % e)
            return ""
            
def create(user, resolution):
    try:
        from ivic.vspace.Server import Singleton
        vspace = VSpace(user, resolution, Singleton.Reporter())
        return vspace
    except Exception, e:
        logger.error("%s" % e) 
        raise
